package net.gyapp.markim.module.message;

import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import com.alibaba.fastjson.JSON;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.easyder.wrapper.base.adapter.ViewHelper;
import com.easyder.wrapper.base.view.WrapperDialog;
import com.easyder.wrapper.core.model.BaseVo;
import com.easyder.wrapper.core.scheduler.Task;
import com.easyder.wrapper.core.scheduler.TaskScheduler;
import com.easyder.wrapper.utils.LogUtils;
import com.lqr.audio.AudioPlayManager;
import com.lqr.emoji.IEmotionSelectedListener;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCompletionHandler;
import com.xuhao.android.libsocket.utils.Logger;

import net.gyapp.markim.ApiConfig;
import net.gyapp.markim.R;
import net.gyapp.markim.WrapperApplication;
import net.gyapp.markim.core.ImHelper;
import net.gyapp.markim.core.ImManager;
import net.gyapp.markim.core.ImProcessor;
import net.gyapp.markim.core.entity.ConversationEntity;
import net.gyapp.markim.core.entity.MemberEntity;
import net.gyapp.markim.core.entity.MessageEntity;
import net.gyapp.markim.module.basic.BaseWebActivity;
import net.gyapp.markim.module.basic.base.CommonPresenter;
import net.gyapp.markim.module.basic.event.AccountChanged;
import net.gyapp.markim.module.basic.event.AccountIml;
import net.gyapp.markim.module.basic.event.GroupChanged;
import net.gyapp.markim.module.basic.event.GroupIml;
import net.gyapp.markim.module.basic.event.MessageChanged;
import net.gyapp.markim.module.basic.event.MessageIml;
import net.gyapp.markim.module.collect.UserIntroduceActivity;
import net.gyapp.markim.module.contact.GroupDetailsActivity;
import net.gyapp.markim.module.contact.UserDetailsActivity;
import net.gyapp.markim.module.contact.vo.GroupProjectVo;
import net.gyapp.markim.module.message.adapter.ConversationAdapter;
import net.gyapp.markim.module.message.bean.QiniuTokenVo;
import net.gyapp.markim.module.message.bean.VoiceBean;
import net.gyapp.markim.module.mine.vo.MemberVo;
import net.gyapp.markim.utils.CommonTools;
import net.gyapp.markim.utils.RequestParams;
import net.gyapp.markim.utils.libs.QiniuManager;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.greenrobot.greendao.query.QueryBuilder;
import org.jim.common.packets.ChatType;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import butterknife.OnClick;
import me.winds.widget.autolayout.utils.AutoUtils;
import me.winds.widget.usage.TitleView;

/**
 * Author:  winds
 * Data:    2018/7/18
 * Version: 1.0
 * Desc:
 */


public class ConversationActivity extends WrapperConversationActivity<CommonPresenter> implements IEmotionSelectedListener {


    protected GroupProjectVo projectVo;
    protected QiniuTokenVo voiceToken;
    protected QiniuTokenVo pictureToken;

    protected ConversationEntity conversation;
    protected ConversationAdapter adapter;

    protected QueryBuilder<MessageEntity> queryBuilder;
    protected int limit = 20;
    protected int page, totalpage;
    protected List<MessageEntity> unSendVoiceMessageList = new ArrayList<>();
    protected List<MessageEntity> unSendImageMessageList = new ArrayList<>();

    public static Intent getIntent(Context context, ConversationEntity conversation) {
        return new Intent(context, ConversationActivity.class).putExtra("conversation", conversation);
    }

    @Override
    protected void initView(Bundle savedInstanceState, TitleView titleView, Intent intent) {
        super.initView(savedInstanceState, titleView, intent);
        getStatusDelegate().getStatusManager().setClearStatusFlag(true);
        conversation = (ConversationEntity) intent.getSerializableExtra("conversation");
        LogUtils.info("--> conversation " + conversation.toString());
        titleView.setCenterText(TextUtils.isEmpty(conversation.name) ? conversation.sessionIdStr : conversation.name);
        if (conversation.chatType == ChatType.CHAT_TYPE_PUBLIC.getNumber()) {
            titleView.setRightImage(R.drawable.group_title);
            titleView.setChildClickListener(R.id.title_iv_right, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(GroupDetailsActivity.getIntent(mActivity, conversation));
                }
            });
        } else {
            titleView.setRightImage(R.drawable.user_titl);
            titleView.setChildClickListener(R.id.title_iv_right, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(UserDetailsActivity.getIntent(mActivity, conversation));
                }
            });
        }
        initAdapter();
    }

    @Override
    protected void loadData(Bundle savedInstanceState, Intent intent) {
        presenter.addFiltersUrl(ApiConfig.API_GET_SMALL_PROGRAM);
        forceRefresh();
    }

    @Override
    public void showContentView(String url, BaseVo dataVo) {
        super.showContentView(url, dataVo);
        if (url.contains(ApiConfig.API_GET_PICTURE_TOKEN)) {
            pictureToken = (QiniuTokenVo) dataVo;
            uploadImageMessage();
        } else if (url.contains(ApiConfig.API_GET_VOICE_TOKEN)) {
            voiceToken = (QiniuTokenVo) dataVo;
            uploadVoiceMessage();
        } else if (url.contains(ApiConfig.API_GET_SMALL_PROGRAM)) {
            processGroupProject((GroupProjectVo) dataVo);
        } else if (url.contains(ApiConfig.API_INFO)) {
            processMemberData((MemberVo) dataVo);
        }
    }

    @Override
    public void onError(com.easyder.wrapper.core.network.ResponseInfo responseInfo) {
        super.onError(responseInfo);
    }

    @Override
    public void processOnErrorStatus(com.easyder.wrapper.core.network.ResponseInfo responseInfo) {
        getStatusDelegate().removeStatus();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case PictureConfig.CHOOSE_REQUEST:
                    obtainMediaResult(PictureSelector.obtainMultipleResult(data));
                    break;
            }
        }
    }

    @Override
    protected void onDestroy() {
        AudioPlayManager.getInstance().stopPlay();
        super.onDestroy();
    }

    @OnClick({R.id.layout_group_project, R.id.layout_album, R.id.layout_shot})
    void click(View view) {
        switch (view.getId()) {
            case R.id.layout_group_project:
                if (projectVo != null) {
                    String url = projectVo.SmallProgram.groupTitleUrl.startsWith("http") ? projectVo.SmallProgram.groupTitleUrl : "http://" + projectVo.SmallProgram.groupTitleUrl;
                    startActivity(BaseWebActivity.getIntent(mActivity, url));
                }
                break;
            case R.id.layout_album:
                showPictureSelector();
                break;
            case R.id.layout_shot:
                PictureSelector.create(this).openCamera(PictureMimeType.ofImage());
                break;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageChanged(MessageChanged changed) {
        switch (changed.sign) {
            case MessageIml.SIGN_CHAT_MESSAGE:
                TaskScheduler.execute(new Task<List<MessageEntity>>() {
                    @Override
                    public List<MessageEntity> doInBackground() throws InterruptedException {
                        return ImHelper.getUnReadMessageList(conversation);
                    }

                    @Override
                    public void onSuccess(List<MessageEntity> result) {
                        addAdapterData(result);
                        LogUtils.info("--> addAdapterData " + result.toString());
                    }
                });
                break;
            case MessageIml.SIGN_MESSAGE_RECALL: //消息撤回
                getMessageList();
                break;
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void accountChanged(AccountChanged changed) {
        if (changed.sign == AccountIml.ACCOUNT_CLEAR_CONVERSATION_CACHE) {
            adapter.getData().clear();
            adapter.notifyDataSetChanged();
        }

        if (changed.sign == AccountIml.ACCOUNT_CONTACT_INFO_CHANGED) {
            conversation = ImHelper.generateConversation(conversation);
            titleView.setCenterText(TextUtils.isEmpty(conversation.name) ? conversation.sessionIdStr : conversation.name);
        }

        if (changed.sign == AccountIml.ACCOUNT_CONTACT_QUIT_GROUP) {
            finish();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void groupChanged(GroupChanged changed) {
        if (conversation != null && conversation.chatType == ChatType.CHAT_TYPE_PUBLIC.getNumber()) {
            if (changed.sign == GroupIml.SIGN_PROJECT_CHANGED) {
                getGroupProject();
            }
        }
    }

    @Override
    public void sendTextMessage(String content) {
        MessageEntity entity = ImManager.getInstance().preGenerateTextMessageEntity(conversation, content, ImHelper.getTimestamp());
        toggleAdapterData(entity);
        sendTextMessage(entity);
    }

    @Override
    protected void sendVoiceMessage(String voiceFilePath, int voiceTimeLength) {
        MessageEntity entity = ImManager.getInstance().preGenerateVoiceMessageEntity(conversation, voiceFilePath, voiceTimeLength, ImHelper.getTimestamp());
        toggleAdapterData(entity);
        uploadVoiceMessage(entity); //此时可添加到列表上 预先展示  正在发送中
    }

    protected void forceRefresh() {
        page = 0;
        getMemberInfo();
        getGroupProject();
        getMessageList(++page);
    }

    protected void getMessageList() {
        page = 0;
        getMessageList(++page);
    }

    private void getMessageList(final int page) {
        TaskScheduler.execute(new Task<List<MessageEntity>>() {
            @Override
            public List<MessageEntity> doInBackground() throws InterruptedException {
                if (queryBuilder == null) {
                    queryBuilder = ImHelper.getMessageQueryBuilder(conversation);
                    if (queryBuilder != null && queryBuilder.count() > 0) {
                        totalpage = CommonTools.getTotalPage((int) queryBuilder.count(), limit);
                    } else {
                        totalpage = 0;
                    }
                }
                if (page > totalpage) {
                    return null;
                } else {
                    return ImHelper.getMessageList(queryBuilder, page, limit);
                }
            }

            @Override
            public void onSuccess(List<MessageEntity> result) {
                if (page == 1) {
                    adapter.setAdapterData(result);
                    if (adapter.getData().size() > 0) {
                        mRecyclerView.moveToPosition(adapter.getItemCount() - 1);
                    }
                    if (conversation.chatType == ChatType.CHAT_TYPE_PRIVATE.getNumber()) {
                        getStatusDelegate().removeStatus();
                    }
                } else { //添加到上层
                    adapter.addAdapterHeadData(result);
                    mRecyclerView.scrollToPosition(result.size());
                }
            }
        });
    }

    private void getGroupProject() {
        if (conversation != null && conversation.chatType == ChatType.CHAT_TYPE_PUBLIC.getNumber()) {
            presenter.setNeedDialog(false);
            presenter.postData(ApiConfig.API_GET_SMALL_PROGRAM, new RequestParams().put("groupNumber", conversation.sessionIdStr).get(), GroupProjectVo.class);
        }
    }

    private void processGroupProject(GroupProjectVo dataVo) {
        if (!TextUtils.isEmpty(dataVo.SmallProgram.groupTitleUrl)) {
            projectVo = dataVo;
            layoutGroupProject.setVisibility(View.VISIBLE);
            tvProjectName.setText(TextUtils.isEmpty(dataVo.SmallProgram.groupTitle) ? "小程序" : dataVo.SmallProgram.groupTitle);
        } else {
            layoutGroupProject.setVisibility(View.GONE);
        }
    }

    /**
     * 添加数据
     *
     * @param entity
     */
    private void addAdapterData(MessageEntity entity) {
        adapter.addAdapterData(entity);
        mRecyclerView.smoothMoveToPosition(adapter.getItemCount() - 1);
    }

    public void toggleAdapterData(MessageEntity entity) {
        adapter.toggleAdapterData(entity);
        mRecyclerView.smoothMoveToPosition(adapter.getItemCount() - 1);
    }

    public void addAdapterData(List<MessageEntity> list) {
        adapter.addAdapterData(list);
        mRecyclerView.smoothMoveToPosition(adapter.getItemCount() - 1);
    }

    private void obtainMediaResult(List<LocalMedia> localMedia) {
        if (localMedia != null && localMedia.size() > 0) {
            sendImageMessage(localMedia.get(0).getPath());
        }
    }

    /**
     * 初始化适配器
     */
    private void initAdapter() {
        adapter = new ConversationAdapter();
        adapter.setUpFetchEnable(true);
        adapter.setUpFetchListener(new BaseQuickAdapter.UpFetchListener() {
            @Override
            public void onUpFetch() {
                if (page < totalpage) {
                    getMessageList(++page);
                }
            }
        });
        adapter.setChatType(ChatType.valueOf(conversation.chatType));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener() {
            @Override
            public void onSimpleItemChildClick(BaseQuickAdapter BaseQuickAdapter, View view, int position) {
                MessageEntity item = adapter.getItem(position);
                switch (view.getId()) {
                    case R.id.rlAudio:
                        adapter.playAudio(view, item, position);
                        break;
                    case R.id.ivAvatar:
                        MemberEntity entity = new MemberEntity();
                        entity.avatar = item.fromAvatar;
                        entity.name = item.fromName;
                        entity.nick = item.fromNick;
                        entity.memberId = item.from;
                        startActivity(UserIntroduceActivity.getIntent(mActivity, entity));
                        break;
                }
            }

            @Override
            public void onItemChildLongClick(BaseQuickAdapter BaseQuickAdapter, View view, int position) {
                if (view.getId() == R.id.tvText) {
                    MessageEntity item = adapter.getItem(position);
                    showMsgToolsDialog(view, position, ImHelper.isSelf(item.from));
                }
            }
        });

//        adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
//            @Override
//            public void onItemChildClick(BaseQuickAdapter baseQuickAdapter, View view, int position) {
//
//            }
//        });
//
//        adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {
//            @Override
//            public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
//                if (view.getId() == R.id.tvText) {
//                    showMsgToolsDialog(view, position % 2 == 0);
//                    return true;
//                }
//                return false;
//            }
//        });
    }

    private void getPictureToken() {
        presenter.setNeedDialog(false);
        presenter.postData(ApiConfig.API_GET_PICTURE_TOKEN, QiniuTokenVo.class);
    }

    private void sendImageMessage(String path) {
        MessageEntity entity = ImManager.getInstance().preGenerateImageMessageEntity(conversation, path, ImHelper.getTimestamp());
        toggleAdapterData(entity);
        uploadImageMessage(entity);
    }

    private void sendImageMessage(MessageEntity entity, String path) {
        entity.content = path;
        sendMessage(entity);
    }

    private void uploadImageMessage(MessageEntity entity) {
        unSendImageMessageList.add(entity);
        if (pictureToken != null) {
            uploadImageMessage(unSendImageMessageList, pictureToken.uptoken);
        } else {
            getPictureToken();
        }
    }

    private void uploadImageMessage() {
        if (pictureToken != null && unSendImageMessageList != null) {
            uploadImageMessage(unSendImageMessageList, pictureToken.uptoken);
        }
    }

    private void uploadImageMessage(final List<MessageEntity> list, final String token) {
        if (list != null && list.size() > 0) {
            final MessageEntity entity = list.get(0);
            File file = new File(entity.content);
            QiniuManager.getInstance().getUploadManager().put(entity.content, file != null ? file.getName() : null, token, new UpCompletionHandler() {

                @Override
                public void complete(String key, ResponseInfo info, JSONObject response) {
                    if (info.isOK()) {
                        Logger.i("key " + key);
                        Logger.i("info " + info.toString());
                        Logger.i("response " + response.toString());

                        try {
                            String path = ImHelper.getActualPicturePath(response);
                            Logger.i("path " + path);
                            sendImageMessage(entity, path);
                            list.remove(entity);
                            uploadImageMessage(list, token);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, null);
        }
    }

    private void sendTextMessage(MessageEntity entity) {
        sendMessage(entity);
    }

    private void getVoiceToken() {
        presenter.setNeedDialog(false);
        presenter.postData(ApiConfig.API_GET_VOICE_TOKEN, QiniuTokenVo.class);
    }

    private void uploadVoiceMessage(final MessageEntity entity) {
        unSendVoiceMessageList.add(entity); //先把未读消息加入队列
        if (voiceToken != null) {
            uploadVoiceMessage(unSendVoiceMessageList, voiceToken.uptoken);
        } else {
            getVoiceToken(); //获取token
        }
    }

    private void uploadVoiceMessage() {
        if (voiceToken != null && unSendVoiceMessageList != null) {
            uploadVoiceMessage(unSendVoiceMessageList, voiceToken.uptoken);
        }
    }

    private void uploadVoiceMessage(final List<MessageEntity> list, final String token) {
        if (list != null && list.size() > 0) {
            final MessageEntity entity = list.get(0);
            String path = entity.voiceLocalPath;
            File file = new File(path);
            QiniuManager.getInstance().getUploadManager().put(entity.voiceLocalPath, file != null ? file.getName() : null, token, new UpCompletionHandler() {

                @Override
                public void complete(String key, ResponseInfo info, JSONObject response) {
                    if (info.isOK()) {
                        Logger.i("key " + key);
                        Logger.i("info " + info.toString());
                        Logger.i("response " + response.toString());

                        try {
                            String path = ImHelper.getActualVoicePath(response);
                            Logger.i("path " + path);
                            sendVoiceMessage(entity, path);
                            list.remove(entity);
                            uploadVoiceMessage(list, token);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, null);
        }
    }

    private void sendVoiceMessage(MessageEntity entity, String qiNiuPath) {
        VoiceBean bean = JSON.parseObject(entity.content, VoiceBean.class);
        bean.voicePath = qiNiuPath;
        entity.content = JSON.toJSONString(bean);
        sendMessage(entity);
    }

    private void onMessageRefresh(MessageEntity entity) {
        toggleAdapterData(entity);
    }

    private void sendMessage(MessageEntity entity) {
        MessageEntity message = ImManager.getInstance().sendMessage(conversation, entity);
        LogUtils.info(" -- MessageEntity -- " + message.toString());
        onMessageRefresh(message);
    }

    private void getMemberInfo() {
        presenter.setNeedDialog(false);
        presenter.postData(ApiConfig.API_INFO, MemberVo.class);
    }

    private void processMemberData(MemberVo dataVo) {
        WrapperApplication.setMember(dataVo);
        if (dataVo.userInfo.userStatus.equalsIgnoreCase("1")) {
            //被禁言
            tvStatus.setVisibility(View.VISIBLE);
        } else {
            tvStatus.setVisibility(View.GONE);
        }
    }


    private void showMsgToolsDialog(final View view, final int position, final boolean isSelf) {

        new WrapperDialog(mActivity) {
            @Override
            public int getLayoutRes() {
                return R.layout.dilaog_recall_msg;
            }

            @Override
            protected void setDialogParams(Dialog dialog) {
                Window window = dialog.getWindow();
                WindowManager.LayoutParams params = window.getAttributes();
                params.width = AutoUtils.getPercentWidthSize(350);
                params.height = AutoUtils.getPercentHeightSize(isSelf ? 320 : 160);
//                params.y = view.getBottom();
//                LogUtils.info("--> y " + params.y);
                window.setGravity(Gravity.CENTER);
                window.setAttributes(params);
            }

            @Override
            public void help(ViewHelper helper) {
                helper.setVisible(R.id.tv_recall, isSelf);
                helper.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        MessageEntity item = adapter.getItem(position);
                        switch (view.getId()) {
                            case R.id.tv_copy:
                                ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                                cm.setPrimaryClip(ClipData.newPlainText(null, item.content));
                                showToast("复制成功");
                                break;
                            case R.id.tv_recall: //撤回
                                if (ImHelper.isSelf(item.from)) {
                                    boolean b = ImManager.getInstance().recallMessage(item);
                                    if (b) {
                                        ImHelper.updateRecallMessage(item);
                                        adapter.notifyDataSetChanged(); //刷新数据源
                                        ImProcessor.processSelfMessageRecallData(conversation, item);
                                    } else {
                                        showToast("撤回失败");
                                    }
                                    Logger.i(" 执行撤回 ");
                                }
                                break;
                        }
                        dismiss();
                    }
                }, R.id.tv_recall, R.id.tv_copy);
            }
        }.show();
    }
}
